<?php
/**
 * 建造者模式
 * 一、定义
 *将一个复杂对象的构造与它的表示分离，
 * 使同样的构建过程可以创建不同的表示。
 * 二、应用场景
 *当一个产品需要复杂的构造，但是构造过程是稳定的，
 * 只是构造的对象有不同表示时，就可以使用建造模式。
 */

class Product{
    public $parts=array();

    public function show(){
          foreach ($this->parts as $k=>$v){
              echo $v."<br/>";
          }
    }
}

abstract class Builder{
    public abstract function BulidPartA();
    public abstract function BulidPartB();
    public abstract function GetResult();
}

class ConcreteBuilder1 extends Builder{

    private $obj=null;

    public function __construct()
    {
        $this->obj=new Product();

    }

    public function BulidPartA()
    {
            $this->obj->parts[]="部件A";
    }

    public function BulidPartB()
    {

        $this->obj->parts[]="部件B";
    }

    public function GetResult()
    {
        return $this->obj;
    }
}

class ConcreteBuilder2 extends Builder{

    private $obj=null;

    public function __construct()
    {
        $this->obj=new Product();
    }

    public function BulidPartA()
    {
        $this->obj->parts[]="部件x";
    }

    public function BulidPartB()
    {
        $this->obj->parts[]="部件y";
    }

    public function GetResult()
    {
        return $this->obj;
    }
}

class Director{
    public function __construct(Builder $obj)
    {
        $obj->BulidPartA();
        $obj->BulidPartB();
    }
}


$b1=new ConcreteBuilder1();
$common1=new Director($b1);
$p1=$b1->GetResult();
$p1->show();

$b2=new ConcreteBuilder2();
$common2=new Director($b2);
$p2=$b2->GetResult();
$p2->show();


/**
 * 外观模式
 * 一、定义：为子系统中的一组接口提供一个一致的界面，Facade模式定义了一个高层接口，这个接口使得这一子系统更加容易使用。
 *二、意图：
 *1 为一个复杂子系统提供一个简单的接口
 *2 减少客户端和子系统的耦合
 *外观(Facade)模式是最简单的模式，我们在开发中不自觉的在使用外观模式，比如我们在三层结构中，DataAccessLayer，BusinessLayer，InterfaceLayer中，通常BusinessLayer组合DataAccessLayer的逻辑，但是在InterfaceLayer层要显示出客户想要的结果，还需要组合和处理各种BusinessLayer中的接口，才能达到想要的显示效果，因为我们就在BusinessLayer和InterfaceLayer之间，在加一层Facade层，这一层把逻辑层的各个接口组合起来，形成统一的接口供InterfaceLayer调用，这样就减少了InterfaceLayer和BusinessLayer层之间的耦合。
 *因为太简单，代码就不写了，Facade模式虽然比较简单，但是是一种重要的编程思想的体现，就是面向对象的低耦合、高内聚，我们在开发过程中，也要尽量的做到让外部调用子系统时，需要了解子系统的东西越少越好，调用代码越简单越好。
 *也就是说把复杂的逻辑封装在子系统中，形成统一简单的接口给外部。不要让外部系统调用时，还需要了解调用系统的内部实现。
 */